/*
 * Copyright (c) 2022 Hong Jiahua
 * https://gitee.com/arrco/jh_priority_queue
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#ifndef __JH_PRIORITY_QUEUE_H__
#define __JH_PRIORITY_QUEUE_H__

#include <string.h>

/**
  * @brief  优先队列数据结构
  */
typedef struct {
    void* base;
    size_t num;
    size_t size;
    size_t data_len;
    int (*compare)(const void*, const void*);
} jh_priority_queue_t;

/**
  * @brief  优先队列数据迭代
  */
#define JH_PQUEUE_ITER(pqueue, item)    \
    for(size_t jh_i = (pqueue)->data_len > 0 ? memcpy(item, (pqueue)->base + (pqueue)->size, (pqueue)->size) , 0 : (pqueue)->data_len; \
        jh_i < (pqueue)->data_len; jh_i++ , jh_i = jh_i < (pqueue)->data_len ? memcpy(item, (pqueue)->base + (jh_i + 1) * (pqueue)->size, (pqueue)->size) , jh_i : jh_i)

/*判断优先队列是否为空*/
int jh_priority_queue_is_empty(jh_priority_queue_t* pqueue);
/*判断优先队列是否已满*/
int jh_priority_queue_is_full(jh_priority_queue_t* pqueue);
/*获取优先队列的数据数量*/
size_t jh_priority_queue_count(jh_priority_queue_t* pqueue);
/*优先队列入队*/
int jh_priority_queue_push(jh_priority_queue_t* pqueue, void* item);
/*优先队列出队*/
int jh_priority_queue_pop(jh_priority_queue_t* pqueue, void* item);
/*优先队列查看队首的数据*/
int jh_priority_queue_peek(jh_priority_queue_t* pqueue, void* item);
/*清空优先队列*/
int jh_priority_queue_clear(jh_priority_queue_t* pqueue);
/*优先队列初始化*/
int jh_priority_queue_init(jh_priority_queue_t* pqueue, void* base, size_t num, size_t size, int (*compare)(const void*, const void*));

#endif